perm filename TEXEXT.SAI[TEX,DEK] blob
sn#568281 filedate 1981-03-05 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00010 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00003 00002 entry begin comment The extension module of TEX.
C00010 00003 internal procedure initext # do this when initializing TEX
C00011 00004 internal procedure extop # do this when "\x" sensed in user input
C00014 00005 internal procedure dumpext(integer p) # do this in procedure dumpnodelist
C00015 00006 internal procedure destroyext(integer p) # do this in procedure dsnodelist
C00016 00007 internal integer procedure copyext(integer p) # do this in procedure boxcopy
C00017 00008 internal procedure hpackext(integer p) # do this in procedure hpackage
C00018 00009 In houtext, x and y are coordinates of the reference point,
C00019 00010 internal procedure finishext # do this just before terminating TEX
C00020 ENDMK
C⊗;
entry; begin comment The extension module of TEX.
In order to extend TEX without changing other modules, you can supply
procedures for the "hooks" internal to this module. Most of these procedures
are called when TEX's routines come up with a case that is ordinarily
undefined (usually when processing a node of type "whatsit").
Whatsit nodes can have variable length. The value field of the first word
of a whatsit should identify what kind of whatsit it is. In the
present extension module the types used are:
0 used for \send
IFPARC 1 for elementary operations of color printing (by L. Guibas) ENDPARC
The "send" routines are based on code developed by Jim Boyce. They appear in
this module because they were the first trial extensions to TEX, although
they are now considered to be "primitives";
require "TEXHDR.SAI" source_file;
internaldef sendnodesize=2 # number of words to allocate for a send node;
internaldef sendstream(p)=⊂value(p+1)⊃ # stream number for tokens to be sent;
internaldef sendtoks(p)=⊂link(p+1)⊃ # token list to be sent;
internal saf integer array sendout["0":"9"] # channel numbers for output streams;
internal boolean firstonpage # no sends to terminal yet on this output page;
IFPARC
comment Warning: these definitions shared among TEXPRS and TEXHDR!!;
internal boolean color;
internal integer curbrightness, curhue, cursaturation;
integer oldbrightness, oldhue, oldsaturation;
define brightness=0, hue=1, saturation=2;
define colornodesize=2 # number of words to allocate for a color node;
define colorwhatsit=1 # type code for color whatsits;
define colorcmd(p)=⊂((mem[p+1] lsh -8) land '3)⊃;
define colorval(p)=⊂(mem[p+1] land '377)⊃;
internal boolean nextfonteightbit;
ENDPARC
internal procedure whatsitappend(integer p) # appends node p to the current list;
begin comment This is somewhat like "simpleappend" in TEXSEM p19;
integer q;
if abs(mode)≠mmode then q←p else
begin comment In math mode, append a "nodenoad";
getavail(q); mem[q]←(nodenoad lsh typed)+(p lsh valued);
end;
mem[curnode]←mem[curnode]+q; curnode←q;
end;
procedure sendit(integer p) # sends token list to the output stream;
begin integer chan,token,tlist; if mem[p+1]=0 then return # already sent;
chan←sendout[sendstream(p)]; tlist←sendtoks(p);
getavail(token); mem[token]←((rbrace lsh cmdd)+"}") lsh infod; inslist(token);
insrclist(tlist); delrclink(tlist);
getavail(token); mem[token]←((lbrace lsh cmdd)+"{") lsh infod; inslist(token);
comment We have prepared to run "{<toklist>}" thru TEX's scanner, as if
scanning an \xdef;
mem[p+1]←0; curcmd←def; hashentry←hashsend; tlist←scantoks;
poptokenlist # remove "}" from input stack;
dumplist(link(tlist),0); dslist(tlist);
if chan<0 then
begin if firstonpage then print(nextline);
print(tokstring[0],nextline);
firstonpage←false;
end
else begin
ifc SUAI or MIT thenc integer i,l; l←length(tokstring[0]);
while l≥150 do
begin comment We will break up the long line so TEX can read it;
i←60;
while i≤l and tokstring[0][i for 1]≠" " do i←i+1;
if i≥150 then done # no way found, just leave it unbroken;
out(chan,tokstring[0][1 to i-1]);
if tokstring[0][i-1 for 1]=escapechar then out(chan," ");
out(chan,nextline);
l←l-i; tokstring[0]←tokstring[0][i+1 to ∞];
end;
endc
out(chan,tokstring[0]); out(chan,nextline);
end;
end;
internal procedure initext # do this when initializing TEX;
begin integer d;
for d←"0" thru "9" do sendout[d]←-1 # all \send channels are closed;
IFPARC curbrightness←0; oldbrightness←0; curhue←0; oldhue←0;
cursaturation←0; oldsaturation←0;
color←false;
nextfonteightbit←false; ENDPARC
end;
internal procedure extop # do this when "\x" sensed in user input;
begin label unknown;
ifc PARC thenc integer octal, i, p;
do getnctok until curcmd ≠ spacer; backinput;
if scanstring("color") then color←true
else if scanstring("nocolor") then color←false
else if scanstring("eightbit") then nextfonteightbit←true
else if color then
begin
p←getnode(colornodesize);
mem[p]←(whatsitnode lsh typed)+(colorwhatsit lsh valued);
octal←0;
if scanstring("brightness") then
begin
mem[p+1]←brightness lsh 8;
for i ← 1 thru 3 do octal←8*octal+scandigit-"0";
if octal > '377 then octal←curbrightness←oldbrightness
else begin oldbrightness←curbrightness; curbrightness←octal; end;
end
else if scanstring("hue") then
begin
mem[p+1]←hue lsh 8;
for i ← 1 thru 3 do octal←8*octal+scandigit-"0";
if octal > '377 then octal←curhue←oldhue
else begin oldhue←curhue; curhue←octal; end;
end
else if scanstring("saturation") then
begin
mem[p+1]←saturation lsh 8;
for i ← 1 thru 3 do octal←8*octal+scandigit-"0";
if octal > '377 then octal←cursaturation←oldsaturation
else begin oldsaturation←cursaturation; cursaturation←octal; end;
end
else error("Unrecognized extension to TEX");
mem[p+1]←mem[p+1]+(octal land '377);
whatsitappend(p);
end;
elsec
unknown: error("Unrecognized extension to TEX");
endc
end;
internal procedure dumpext(integer p) # do this in procedure dumpnodelist;
case value(p) of begin
[0] if mem[p+1] then begin comment \send;
string s; dumplist(link(sendtoks(p)),0); s←tokstring[0];
if length(s)>30 then s←s[1 to 30]&"...\ETC";
print("\send ",sendstream(p)&"{",s,"}") end else print("\sent");
IFPARC
[colorwhatsit] case colorcmd(p) of begin
[brightness] print("\x brightness '"&cvos(colorval(p)));
[hue] print("\x hue '"&cvos(colorval(p)));
[saturation] print("\x saturation '"&cvos(colorval(p)));
else confusion
end;
ENDPARC
else print("whatsit?!")
end;
internal procedure destroyext(integer p) # do this in procedure dsnodelist;
case value(p) of begin
[0] begin if mem[p+1] then delrclink(sendtoks(p)); freenode(p,sendnodesize) end;
IFPARC [colorwhatsit] freenode(p,colornodesize); ENDPARC
else errorstop("Dry rot--bad extension [unknown case in destroyext]")
end;
internal integer procedure copyext(integer p) # do this in procedure boxcopy;
begin integer r;
case value(p) of begin
[0] begin integer q; r←getnode(sendnodesize); mem[r]←whatsitnode lsh typed;
mem[r+1]←mem[p+1]; q←sendtoks(r); if q then mem[q]←mem[q]+refct1 end;
IFPARC
[colorwhatsit] begin r←getnode(colornodesize); mem[r+1]←mem[p+1];
mem[r]←(whatsitnode lsh typed)+(colorwhatsit lsh valued) end;
ENDPARC
else errorstop("Dry rot--bad extension [unknown case in copyext]")
end;
return(r);
end;
internal procedure hpackext(integer p) # do this in procedure hpackage;
;
internal procedure vpackext(integer p) # do this in procedure vpackage;
;
internal procedure pageext(integer p) # do this in the addtopage routine;
;
internal procedure justext(integer p) # do this in the justification routine;
;
comment In houtext, x and y are coordinates of the reference point,
while in voutext they are coordinates of the upper left corner;
internal procedure houtext(integer p; reference real x,y) # do this in shipout;
case value(p) of begin
[0] sendit(p);
IFPARC [colorwhatsit] if color then PutColor(colorcmd(p),colorval(p)); ENDPARC
else comment do nothing;
end;
internal procedure voutext(integer p; reference real x,y) # do this in shipout;
case value(p) of begin
[0] sendit(p);
IFPARC [colorwhatsit] if color then PutColor(colorcmd(p),colorval(p)); ENDPARC
else comment do nothing;
end;
internal procedure finishext # do this just before terminating TEX;
begin integer d;
for d←"0" thru "9" do
begin if sendout[d]≥0 then release(sendout[d]);
end;
end;
end